from docx import Document
from docx.oxml.ns import qn
import re
import json
import json_repair
import requests

#调用大模型
def dify_chat(query):
    # global pool_sema
    # # 开启线程限制
    # with pool_sema:
    url = 'http://192.168.43.12:8083/v1/chat-messages'  # v1/chat-messages'调用聊天框  workflows/run智能体
    api_key = 'app-ya62uFf28a59TSX3vykntOlu'  # 'app-ldimOhba65Dq5BlHpPXQaDka'  # 替换为您的实际API密钥

    # 请求头
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }

    # 请求数据
    data = {
        "inputs": {},
        "query": query,
        "response_mode": "streaming",  # blocking streaming
        "conversation_id": "",
        "user": "abc-123",
    }

    # 将数据转换为JSON字符串
    data_json = json.dumps(data)

    answer = ''

    # 发送GET请求，并设置stream=True
    with requests.post(url, headers=headers, data=data_json.encode("utf-8"), stream=True) as r:
        # 检查请求是否成功
        r.raise_for_status()

        # 打印每一行文本
        for line in r.iter_lines():

            # 忽略保持连接的空行
            if line:
                # 解码每一行，因为返回的数据可能是字节串
                line = line.decode('utf-8')
                if 'data: ' in line:
                    data = json.loads(line.replace('data: ', ''))
                    if data['event'] == 'message':
                        # print(data['answer'])
                        answer += data['answer']
                        print(data['answer'],end='')
                    elif data['event'] == 'message_end':
                        break

    #去除思考过程
    answer = answer.split('</think>')[-1]

    return answer

#获取大模型json结果
def json_process(data_answ):
    pattern = r'```json(.*?)```'
    matches = re.findall(pattern, data_answ, re.DOTALL)  # 抽取出内容并判断长度
    if matches:
        c_statement = json_repair.loads(matches[-1])
        # print("\n-------step2查到的对应的内容为：\n", c_statement)
    else:
        c_statement = {}
    # decoded_object = json_repair.loads(c_statement)
    # return json.dumps(decoded_object,ensure_ascii=False)
    return c_statement

#在指定位置添加一行
def insert_row(table, row_index):

    # 在指定位置插入一行
    table.add_row()

    # 移动新插入的行到指定位置
    rows = table.rows
    rows[row_index]._element.getparent().insert(
        rows[row_index]._element.getparent().index(rows[row_index]._element), rows[-1]._element
    )
    rows[-1]._element.getparent().remove(rows[-1]._element)

    return table

#docx添加内容
def docx_add(table, result, save_path):

    table_rows = table.rows
    table_row_index = 0
    data_row_index = 0
    while data_row_index < len(result):

        data_row = result[data_row_index]
        print(data_row)

        # 在末尾添加一行新的行
        if table_row_index >= len(table_rows):
            print(len(table_rows))
            table.add_row()
            # 更新table和cells
            table_rows = table.rows
            print(len(table_rows))
            continue

        # 获取该行第一个单元格的内容
        first_cell_text = table_rows[table_row_index].cells[0].text

        # 如果内容不为标题但是该单元格有内容不为省略号并且单元格内容和填充内容不同，则代表该行需要新增一行
        if not data_row[0].startswith('标题：') and first_cell_text and first_cell_text != data_row[0] and first_cell_text!='……':
            table = insert_row(table, table_row_index)
            # 更新table和cells
            table_rows = table.rows
            continue
        else:
            cells = table_rows[table_row_index].cells

        # 先遍历该行，判断是否为空分割行
        ls = []
        for j, cell in enumerate(cells):
            if cell not in cells[:j]:
                ls.append(cell.text)

        # 如果该行为空分割行，则跳到表格下一行
        if len(ls) == 1 and not ls[0]:
            # 内容不为标题，则新增一行
            if not data_row[0].startswith('标题：'):
                table = insert_row(table, table_row_index)
                # 更新table和cells
                table_rows = table.rows
                continue
            else:
                table_row_index += 1
                continue

        # 查找标题所在的行
        if data_row[0].startswith('标题：') and (not first_cell_text or first_cell_text == '……'):
            # 删除该行
            # 获取底层 XML 元素
            tr = table.rows[table_row_index]._element
            # 从表格中移除该行
            tr.getparent().remove(tr)
            # 更新table和cells
            table_rows = table.rows
            continue

        for j, text in enumerate(data_row):
            # 如果单元格为空或者未省略号，则填充
            if not cells[j].text or cells[j].text == '……':
                # cells[j].text = text

                # 如果单元格内已有段落，则获取；否则添加一个新的段落
                if cells[j].paragraphs:
                    paragraph = cells[j].paragraphs[0]
                else:
                    paragraph = cells[j].add_paragraph()

                paragraph.text = text
                run = paragraph.runs[0]

                # 字体样式为宋体5号字
                run.font.name = '宋体'
                run._element.rPr.rFonts.set(qn('w:eastAsia'), run.font.name)

        # 下一行数据
        data_row_index += 1
        table_row_index += 1

    # 删除多余的空行
    if table_row_index < len(table_rows):
        # 获取该行第一个单元格的内容
        first_cell_text = table_rows[table_row_index].cells[0].text
        if first_cell_text == '……' or not first_cell_text:
            # 获取底层 XML 元素
            tr = table.rows[table_row_index]._element
            # 从表格中移除该行
            tr.getparent().remove(tr)
            # 更新table和cells
            table_rows = table.rows

    doc.save(save_path)

#获取表格内容
doc = Document('/media/977GB/wcj_work/禅道/新视图开发/zentao/bid/文档/商务文件模板/7_投标人重要信息情况表_标的1：业务系统2024年第五批采购项目.docx')

tables = doc.tables

for table in tables:
    #获取表格内容
    ls = []

    for row in table.rows:
        row_ls = []
        cells = row.cells
        for i,cell in enumerate(cells):
            if cell not in cells[:i]:
                row_ls.append(cell.text)

        #如果该行没有空值，则认为该行为横向标题行
        if '' not in row_ls:
            row_ls[0] = '标题：'+row_ls[0]
        ls.append(row_ls)

    # 调用大模型获取结果
    # 提示词
    prompt = '''
        根据传入的二维数组表格以及相关信息，补充表格信息，填充空行，删除省略号行，其余行不变，以下为参考样例
        <参考样例>
        <输入>
        <表格>
        [["姓名", "", "性别", ""], ["语文", "", "数学", ""], ["评价", "", "", ""]]
        </表格>
        <信息>
        {"姓名": "王五", "性别": "男", "语文": "95", "数学": "88", "评价": "优"}
        </信息>
        </输入>
        <输出>
        ```json
        [["姓名", "王五", "性别", "男"], ["语文", "95", "数学", "88"], ["评价", "优", "", ""]]
        ```
        </输出>
        </参考样例>
        '''

    basic_info = {"标的名称": "标的2：数字化技术平台2024 年第五批采购项目", "标包名称": "标包1：北斗运营服务应用V3.0（安全升级改造）建设项目", "投标人":"南方电网数字企业科技(广东)有限公司", "时间": "2024-12-09 21:34:52", "法人姓名": "曹旭", "法人性别": "男", "法人年龄": 35, "法人职务": "董事长","序号":"1", "质量":"无质量问题", "服务期/交货期": "1、9个月\n2、6个月","项目负责人":"肖建毅","项目负责人证书":"1.PMP\n2.测试\n3.222"}
    llm_input_text = f'''
        <表格>
        {ls}
        </表格>
        <信息>
        {basic_info}
        </信息>
        '''
    print(llm_input_text)
    # 调用大模型
    query = f"{prompt}{llm_input_text}"
    answer = dify_chat(query)

    # 将结果转为json
    result = json_process(answer)

    docx_add(table, result, '1111.docx')
